package com.app.base
{
	import com.app.components.Global;
	import com.app.events.ControlEvent;
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TouchEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.ui.Multitouch;
	import flash.ui.MultitouchInputMode;
	import flash.utils.getTimer;
	
	[Event(name="control_down", type="com.app.events.ControlEvent")]
	[Event(name="control_up", type="com.app.events.ControlEvent")]
	[Event(name="control_move", type="com.app.events.ControlEvent")]
	[Event(name="control_click", type="com.app.events.ControlEvent")]
	[Event(name="control_over", type="com.app.events.ControlEvent")]
	[Event(name="control_out", type="com.app.events.ControlEvent")]
	[Event(name="control_roll_over", type="com.app.events.ControlEvent")]
	[Event(name="control_roll_out", type="com.app.events.ControlEvent")]
	[Event(name="control_drag_start", type="com.app.events.ControlEvent")]
	[Event(name="control_drag_move", type="com.app.events.ControlEvent")]
	[Event(name="control_drag_stop", type="com.app.events.ControlEvent")]
	[Event(name="control_drag_cast", type="com.app.events.ControlEvent")]
	
	public class Display extends MovieClip
	{
		//拖动相关
		private var _drag:Boolean;
		
		public function Display()
		{
			super();
		}
		
		
		
		/**------------------------------------------------------------------------------------
		 * 
		 * get set 
		 * 
		 -------------------------------------------------------------------------------------*/
		
		/** 是否启用拖动事件 */ 
		public function get drag():Boolean {return _drag;}
		public function set drag(value:Boolean):void
		{
			_drag = value;
			useDragHandler();
		}
		
		
		
		/**------------------------------------------------------------------------------------
		 * 
		 * 拖动处理
		 * 
		 -------------------------------------------------------------------------------------*/
		
		private var _startPoint:Point = new Point();
		private var _endPoint:Point = new Point();
		private var _dragMove:Boolean;
		private var _controlTimer:int;
		
		private function useDragHandler():void
		{
			if(_drag)
			{
				if(Multitouch.inputMode == MultitouchInputMode.NONE)
				{
					addEventListener(MouseEvent.MOUSE_DOWN ,dragMouseHandler);
				}else{
					addEventListener(TouchEvent.TOUCH_BEGIN ,dragTouchHandler);
				}
			}else{
				removeEventListener(MouseEvent.MOUSE_DOWN ,dragMouseHandler);
				removeEventListener(TouchEvent.TOUCH_BEGIN ,dragTouchHandler);
				if(stage)
				{
					stage.removeEventListener(MouseEvent.MOUSE_MOVE ,dragMouseHandler);
					stage.removeEventListener(TouchEvent.TOUCH_MOVE ,dragTouchHandler);
					stage.removeEventListener(MouseEvent.MOUSE_UP ,dragMouseHandler);
					stage.removeEventListener(TouchEvent.TOUCH_END ,dragTouchHandler);
				}
			}
		}
		
		
		/** MouseEvent */
		private function dragMouseHandler(event:MouseEvent):void
		{
			dragHandler(event.type);
		}
		
		/** ToucehEvent */
		private function dragTouchHandler(event:TouchEvent):void
		{
			if(event.touchPointID!=0)return;
			dragHandler(event.type);
		}
		
		/** 主逻辑处理 */
		private function dragHandler(type:String):void
		{
			switch(type)
			{
				case MouseEvent.MOUSE_DOWN:case TouchEvent.TOUCH_BEGIN:
					_dragMove = false;
					_startPoint.x = mouseX;
					_startPoint.y = mouseY;
					_controlTimer = getTimer();
					stage.addEventListener(MouseEvent.MOUSE_MOVE ,dragMouseHandler);
					stage.addEventListener(TouchEvent.TOUCH_MOVE ,dragTouchHandler);
					stage.addEventListener(MouseEvent.MOUSE_UP ,dragMouseHandler);
					stage.addEventListener(TouchEvent.TOUCH_END ,dragTouchHandler);
					return;
					
				case MouseEvent.MOUSE_MOVE:case TouchEvent.TOUCH_MOVE:
					_endPoint.x = mouseX;
					_endPoint.y = mouseY;
					
					if(!_dragMove)
					{
						_dragMove = true;
						dragDispatchHandler(ControlEvent.DRAG_START);
						
						/** 通知所有正在移动 */
						Global.eventDispatcher.dispatchEvent(new ControlEvent(ControlEvent.DRAG_START ,null));
					}
					
					if(_dragMove)
					{
						dragDispatchHandler(ControlEvent.DRAG_MOVE);
					}
					return;
					
				case MouseEvent.MOUSE_UP:case TouchEvent.TOUCH_END:
					stage.removeEventListener(MouseEvent.MOUSE_MOVE ,dragMouseHandler);
					stage.removeEventListener(TouchEvent.TOUCH_MOVE ,dragTouchHandler);
					stage.removeEventListener(MouseEvent.MOUSE_UP ,dragMouseHandler);
					stage.removeEventListener(TouchEvent.TOUCH_END ,dragTouchHandler);
					_endPoint.x = mouseX;
					_endPoint.y = mouseY;
					
					if(_dragMove)
					{
						dragDispatchHandler(ControlEvent.DRAG_STOP);
						
						if(getTimer()-_controlTimer<200)
							dragDispatchHandler(ControlEvent.DRAG_CAST);
					}
					
					_dragMove = false;
					
					/** 通知所有正在移动结束 */
					Global.eventDispatcher.dispatchEvent(new ControlEvent(ControlEvent.DRAG_STOP ,null));
					return;
			}
		}
		
		/** 发送事件，并设置对应参数 */
		private function dragDispatchHandler(type:String):void
		{
			var data:Object = new Object();
			data.startPoint = _startPoint;
			data.endPoint = _endPoint;
			data.direction = getDirection(_startPoint ,_endPoint);
			dispatchEvent(new ControlEvent(type ,data));
		}
		
		/** 计算方向 */
		private function getDirection(start:Point ,end:Point):int
		{
			if(Math.abs(end.y-start.y)>Math.abs(end.x-start.x))
			{
				return end.y<start.y?0:1;
			}else{
				return end.x<start.x?2:3;
			}
		}
		
		
		
		
		
		/**------------------------------------------------------------------------------------
		 * 
		 * Mouse 与 Touch 转换处理
		 * 
		 -------------------------------------------------------------------------------------*/
		override public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			super.addEventListener(type, listener, useCapture, priority, useWeakReference);
			
			if(Multitouch.inputMode == MultitouchInputMode.NONE)
			{
				switch(type)
				{
					case ControlEvent.DOWN:			addEventListener(MouseEvent.MOUSE_DOWN ,mouseHandler);		return;
					case ControlEvent.UP:			addEventListener(MouseEvent.MOUSE_UP ,mouseHandler);		return;
					case ControlEvent.MOVE:			addEventListener(MouseEvent.MOUSE_MOVE ,mouseHandler);		return;
					case ControlEvent.CLICK:		addEventListener(MouseEvent.CLICK ,mouseHandler);			return;
					case ControlEvent.OVER:			addEventListener(MouseEvent.MOUSE_OVER ,mouseHandler);		return;
					case ControlEvent.OUT:			addEventListener(MouseEvent.MOUSE_OUT ,mouseHandler);		return;
					case ControlEvent.ROLL_OVER:	addEventListener(MouseEvent.ROLL_OVER ,mouseHandler);		return;
					case ControlEvent.ROLL_OUT:		addEventListener(MouseEvent.ROLL_OUT ,mouseHandler);		return;
				}
			}else{
				switch(type)
				{
					case ControlEvent.DOWN:			addEventListener(TouchEvent.TOUCH_BEGIN ,touchHandler);		return;
					case ControlEvent.UP:			addEventListener(TouchEvent.TOUCH_END ,touchHandler);		return;
					case ControlEvent.MOVE:			addEventListener(TouchEvent.TOUCH_MOVE ,touchHandler);		return;
					case ControlEvent.CLICK:		addEventListener(TouchEvent.TOUCH_TAP ,touchHandler);		return;
					case ControlEvent.OVER:			addEventListener(TouchEvent.TOUCH_OVER ,touchHandler);		return;
					case ControlEvent.OUT:			addEventListener(TouchEvent.TOUCH_OUT ,touchHandler);		return;
					case ControlEvent.ROLL_OVER:	addEventListener(TouchEvent.TOUCH_ROLL_OVER ,touchHandler);	return;
					case ControlEvent.ROLL_OUT:		addEventListener(TouchEvent.TOUCH_ROLL_OUT ,touchHandler);	return;
				}
			}
		}
		
		override public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			super.removeEventListener(type, listener, useCapture);
			
			switch(type)
			{
				case ControlEvent.DOWN:			
					removeEventListener(MouseEvent.MOUSE_DOWN ,mouseHandler);
					removeEventListener(TouchEvent.TOUCH_BEGIN ,touchHandler);
					return;
				case ControlEvent.UP:			
					removeEventListener(MouseEvent.MOUSE_UP ,mouseHandler);			
					removeEventListener(TouchEvent.TOUCH_END ,touchHandler);
					return;
				case ControlEvent.MOVE:			
					removeEventListener(MouseEvent.MOUSE_MOVE ,mouseHandler);
					removeEventListener(TouchEvent.TOUCH_MOVE ,touchHandler);
					return;
				case ControlEvent.CLICK:		
					removeEventListener(MouseEvent.CLICK ,mouseHandler);
					removeEventListener(TouchEvent.TOUCH_TAP ,touchHandler);
					return;
				case ControlEvent.OVER:			
					removeEventListener(MouseEvent.MOUSE_OVER ,mouseHandler);		
					removeEventListener(TouchEvent.TOUCH_OVER ,touchHandler);
					return;
				case ControlEvent.OUT:			
					removeEventListener(MouseEvent.MOUSE_OUT ,mouseHandler);
					removeEventListener(TouchEvent.TOUCH_OUT ,touchHandler);
					return;
				case ControlEvent.ROLL_OVER:	
					removeEventListener(MouseEvent.ROLL_OVER ,mouseHandler);			
					removeEventListener(TouchEvent.TOUCH_ROLL_OVER ,touchHandler);
					return;
				case ControlEvent.ROLL_OUT:		
					removeEventListener(MouseEvent.ROLL_OUT ,mouseHandler);			
					removeEventListener(TouchEvent.TOUCH_ROLL_OUT ,touchHandler);
					return;
			}
		}
		
		private function mouseHandler(event:MouseEvent):void
		{
			var data:Object = new Object();
			data.localX = event.localX;
			data.localY = event.localY;
			data.stageX = event.stageX;
			data.stageY = event.stageY;
			
			data.touchPointID = 0;
			data.pressure = 0;
			data.sizeX = 0;
			data.sizeY = 0;
			data.timestamp = getTimer();
			
			dispatchHandler(event.type ,data);
		}
		
		private function touchHandler(event:TouchEvent):void
		{
			var data:Object = new Object();
			data.localX = event.localX;
			data.localY = event.localY;
			data.stageX = event.stageX;
			data.stageY = event.stageY;
			
			data.touchPointID = event.touchPointID;
			data.pressure = event.pressure;
			data.sizeX = event.sizeX;
			data.sizeY = event.sizeY;
			data.timestamp = getTimer();//event.timestamp;
			
			dispatchHandler(event.type ,data);
		}
		
		private function dispatchHandler(type:String ,data:Object):void
		{
			switch(type)
			{
				case MouseEvent.MOUSE_DOWN:			dispatchEvent(new ControlEvent(ControlEvent.DOWN ,data));		return;
				case MouseEvent.MOUSE_UP:			dispatchEvent(new ControlEvent(ControlEvent.UP ,data));			return;
				case MouseEvent.MOUSE_MOVE:			dispatchEvent(new ControlEvent(ControlEvent.MOVE ,data));		return;
				case MouseEvent.CLICK:				dispatchEvent(new ControlEvent(ControlEvent.CLICK ,data));		return;
				case MouseEvent.MOUSE_OVER:			dispatchEvent(new ControlEvent(ControlEvent.OVER ,data));		return;
				case MouseEvent.MOUSE_OUT:			dispatchEvent(new ControlEvent(ControlEvent.OUT ,data));		return;
				case MouseEvent.ROLL_OVER:			dispatchEvent(new ControlEvent(ControlEvent.ROLL_OVER ,data));	return;
				case MouseEvent.ROLL_OUT:			dispatchEvent(new ControlEvent(ControlEvent.ROLL_OUT ,data));	return;
					
				case TouchEvent.TOUCH_BEGIN:		dispatchEvent(new ControlEvent(ControlEvent.DOWN ,data));		return;
				case TouchEvent.TOUCH_END:			dispatchEvent(new ControlEvent(ControlEvent.UP ,data));			return;
				case TouchEvent.TOUCH_MOVE:			dispatchEvent(new ControlEvent(ControlEvent.MOVE ,data));		return;
				case TouchEvent.TOUCH_TAP:			dispatchEvent(new ControlEvent(ControlEvent.CLICK ,data));		return;
				case TouchEvent.TOUCH_OVER:			dispatchEvent(new ControlEvent(ControlEvent.OVER ,data));		return;
				case TouchEvent.TOUCH_OUT:			dispatchEvent(new ControlEvent(ControlEvent.OUT ,data));		return;
				case TouchEvent.TOUCH_ROLL_OVER:	dispatchEvent(new ControlEvent(ControlEvent.ROLL_OVER ,data));	return;
				case TouchEvent.TOUCH_ROLL_OUT:		dispatchEvent(new ControlEvent(ControlEvent.ROLL_OUT ,data));	return;
			}
		}
	}
}